<template>
  <div class="app-container">
    <!-- 查询条件 -->
    <el-form :model="queryParams" ref="searchForm" label-width="80px" :inline="true" size="small">
      <el-form-item label="角色名称">
        <el-input v-model="queryParams.data.roleName" placeholder="请输入角色名称" clearable />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" @click="search()">查询</el-button>
        <el-button icon="el-icon-refresh-right" @click="reset()">重置</el-button>
        <el-button type="success" icon="el-icon-plus" @click="openAddWindow()">新增</el-button>
        <!-- <el-button type="warning" icon="el-icon-plus" @click="handleExcel()">导出</el-button> -->
      </el-form-item>
    </el-form>
    <!-- 数据表格 -->
    <el-table :data="tableData" stripe style="width: 100%; margin-bottom: 10px">
      <el-table-column prop="roleId" label="角色编号" width="100px" align="center" />
      <el-table-column prop="roleName" label="角色名称" align="center" />
      <el-table-column prop="roleKey" label="权限字符" align="center" />
      <el-table-column prop="roleSort" label="顺序" align="center" />
      <el-table-column prop="status" label="状态" align="center">
        <template slot-scope="scope">
          <el-tag>
            <span v-if="scope.row.status == 0">正常</span>
            <span v-if="scope.row.status == 1">停用</span>
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column prop="createTime" label="创建时间" align="center" />
      <el-table-column prop="remark" label="角色备注" align="center" />
      <el-table-column label="操作" align="center" width="290px">
        <template slot-scope="scope">
          <el-button icon="el-icon-edit" type="primary" size="small" @click="handleEdit(scope.row)">编辑
          </el-button>
          <el-button icon="el-icon-delete" type="danger" size="small" @click="handleDelete(scope.row)">删除
          </el-button>
          <el-button icon="el-icon-setting" type="primary" size="small" @click="assignRole(scope.row)">分配权限
          </el-button>
        </template>
      </el-table-column>
    </el-table>
    <!-- 分页工具栏 -->
    <el-pagination background align="right" :current-page="queryParams.page.current" 
      :page-sizes="[10, 20, 30, 40, 50]" :page-size="queryParams.page.size" layout="total, sizes, prev, pager, next, jumper" 
      :total="total" @size-change="handleSizeChange" @current-change="handleCurrentChange">
    </el-pagination>

    <!-- 添加和修改角色窗口 -->
    <system-dialog :title="roleDialog.title" :visible="roleDialog.visible" :width="roleDialog.width" :height="roleDialog.height" @onClose="onClose" @onConfirm="onConfirm">
      <div slot="content">
        <el-form :model="role" ref="roleForm" :rules="rules" label-width="80px" :inline="false" size="small">
          <el-form-item label="角色名称" prop="roleName">
            <el-input v-model="role.roleName"></el-input>
          </el-form-item>
          <el-form-item label="角色编码" prop="roleKey">
            <el-input v-model="role.roleKey"></el-input>
          </el-form-item>
          <el-form-item size="small" label="角色顺序" prop="roleSort">
            <el-input-number v-model="role.roleSort" controls-position="right" :min="0" />
          </el-form-item>
          <el-form-item size="small" label="状态" prop="status">
            <el-radio-group v-model="role.status">
              <el-radio label="0">正常</el-radio>
              <el-radio label="1">禁用</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item label="角色描述">
            <el-input type="textarea" v-model="role.remark" :rows="3"></el-input>
          </el-form-item>
        </el-form>
      </div>
    </system-dialog>

    <!-- 分配权限树窗口 -->
    <system-dialog :title="assignDialog.title" :visible="assignDialog.visible" :width="assignDialog.width" :height="assignDialog.height" @onClose="onAssignClose" @onConfirm="onAssignConfirm">
      <div slot="content">
        <el-tree ref="assignTree" :data="assignTreeData" node-key="menuId" :props="defaultProps" empty-text="暂无数据" :show-checkbox="true" :highlight-current="true" default-expand-all></el-tree>
      </div>
    </system-dialog>
  </div>
</template>

<script>
import roleApi from "@/api/system/role";
//导入对话框组件
import SystemDialog from "@/components/system/SystemDialog.vue";
//导入末级节点脚本
import leafUtils from "@/utils/leaf";

export default {
  name: "Role",
  components: { SystemDialog },
  data() {
    return {
      // 查询条件
      searchModel: {
        roleName: "",
        pageNo: 1,
        pageSize: 10,
        //当前登录用户id
        userId: this.$store.getters.userId,
      },

      // 当前页码
      pageNo: 1,
      //每页显示数量
      pageSize: 10,
      // 表格数据
      tableData: [],
      // 总条数
      total: 0,
      // 查询部分参数
      queryParams: {
        page: {
          current: 1,
          size: 10
        },
        data: {

        }
      },

      //角色对象
      role: {},
      //添加和修改角色窗口属性
      roleDialog: {
        title: "",
        visible: false,
        height: 320,
        width: 450,
      },
      // 表单校验
      rules: {
        roleName: [
          { required: true, trigger: "blur", message: "请输入角色名称" },
        ],
        roleKey: [
          { required: true, trigger: "blur", message: "请输入角色编码" },
        ],
        roleSort: [
          { required: true, trigger: "change", message: "请选择角色顺序" },
        ],
        status: [{ required: true, trigger: "change", message: "请选择状态" }],
      },

      //分配权限窗口属性
      assignDialog: {
        title: "",
        visible: false,
        height: 450,
        width: 300,
      },
      //角色ID
      roleId: "",
      //树节点数据
      assignTreeData: [],
      //树节点属性
      defaultProps: {
        children: "children",
        label: "label",
      },
    };
  },
  created() {
    this.search();
  },
  methods: {
    //查询角色列表
    async search() {
      let res = await roleApi.getRolePage(this.queryParams);
      //执行成功
      if (res.success) {
        //角色列表
        this.tableData = res.data.records;
        //总数量
        this.total = res.data.total;
      }
    },
    //重置查询条件
    reset() {
      this.queryParams = {
        page: {
          current: 1,
          size: 10
        },
        data: {}
      }
      this.search();
    },
    //打开新增对话框
    openAddWindow() {
      this.$resetForm("roleForm", this.role);
      this.roleDialog.title = "新增角色";
      this.roleDialog.visible = true;
    },
    //导出excel
    handleExcel() {
      if (this.total === 0) {
        return this.$message.error("查询数据为空，不进行导出操作！");
      }
    },
    //当每页数量发生变化时触发的事件
    handleSizeChange(pageSize) {
      this.queryParams.page.size = pageSize;
      this.search();
    },
    //当页码发生变化时触发的事件
    handleCurrentChange(currentPage) {
      this.queryParams.page.current = currentPage;
      this.search();
    },
    //窗口取消事件
    onClose() {
      this.roleDialog.visible = false;
    },
    //窗口确认事件
    onConfirm() {
      //表单验证
      this.$refs.roleForm.validate(async (valid) => {
        if (valid) {
          let res = null;
          if (this.role.roleId == undefined) {
            res = await roleApi.addRole(this.role);
          } else {
            res = await roleApi.updateRole(this.role);
          }
          if (res.success) {
            this.$message.success(res.message);
            this.search();
            this.roleDialog.visible = false;
          } else {
            this.$message.error(res.message);
            this.roleDialog.visible = false;
          }
        }
      });
    },
    //修改按钮
    handleEdit(row) {
      this.role = row;
      this.roleDialog.title = "修改角色";
      this.roleDialog.visible = true;
    },
    //删除按钮
    async handleDelete(row) {
      //检查角色是否被分配出去
      let result = await roleApi.getCheckRole({ roleId: row.roleId });
      //判断是否可以删除
      if (!result.success) {
        //提示不能删除
        this.$message.warning(result.message);
      } else {
        //确认是否删除
        let confirm = await this.$myconfirm("确定要删除该数据吗?");
        if (confirm) {
          //发送删除请求
          let res = await roleApi.deleteRole({ roleId: row.roleId });
          //判断是否成功
          if (res.success) {
            //成功提示
            this.$message.success(res.message);
            //刷新
            this.search();
          } else {
            //失败提示
            this.$message.error(res.message);
          }
        }
      }
    },
    //分配权限
    async assignRole(row) {
      //设置角色ID
      this.roleId = row.roleId;
      //发送查询请求
      let res = await roleApi.getAssignMenuTree({ roleId: row.roleId });
      //判断是否成功
      if (res.success) {
        //获取当前登录用户拥有的所有权限
        let menuList = res.data.menuList;
        //获取当前被分配角色已经拥有的权限信息
        let checkList = res.data.checkList;
        //判断当前菜单是否是末级
        let { setLeaf } = leafUtils();
        //设置权限菜单列表
        let newMenuList = setLeaf(menuList);
        //设置树节点菜单数据
        this.assignTreeData = newMenuList;
        //将回调延迟到下次DOM更新循环之后执行,在修改数据之后立即使用它,然后等待DOM更新。
        this.$nextTick(() => {
          //获取树菜单的节点数据
          let nodes = this.$refs.assignTree.children;
          //设置子节点
          this.setChild(nodes, checkList);
        });
      }
      //显示窗口
      this.assignDialog.visible = true;
      //设置窗口标题
      this.assignDialog.title = `给【${row.roleName}】分配权限`;
    },
    //设置子节点
    setChild(childNodes, checkList) {
      //判断是否存在子节点
      if (childNodes && childNodes.length > 0) {
        //循环所有权限
        for (let i = 0; i < childNodes.length; i++) {
          //根据 data 或者 key 拿到 Tree 组件中的 node
          let node = this.$refs.assignTree.getNode(childNodes[i]);
          //判断是否已经拥有对应的角色数据
          if (checkList && checkList.length > 0) {
            //循环遍历已有的权限集合
            for (let j = 0; j < checkList.length; j++) {
              //找到已经存在的菜单权限节点
              if (checkList[j] == childNodes[i].menuId) {
                //如果节点是展开状态，则将树节点选中
                if (childNodes[i].open) {
                  this.$refs.assignTree.setChecked(node, true);
                  break;
                }
              }
            }
          }
          //如果存在子节点，则递归选中
          if (childNodes[i].children) {
            this.setChild(childNodes[i].children, checkList);
          }
        }
      }
    },
    //分配权限窗口取消事件
    onAssignClose() {
      this.assignDialog.visible = false;
    },
    //分配权限窗口确认事件
    async onAssignConfirm() {
      //获取选中的节点key
      let ids = this.$refs.assignTree.getCheckedKeys();
      //获取选中节点的父节点id
      let pids = this.$refs.assignTree.getHalfCheckedKeys();
      //组装选中的节点ID数据
      let listId = ids.concat(pids);
      //组装参数
      let params = {
        roleId: this.roleId,
        list: listId,
      };
      let res = await roleApi.saveRoleAssign(params);
      if (res.success) {
        this.assignDialog.visible = false;
        this.$message.success(res.message);
      } else {
        this.$message.error(res.data);
      }
    },
  },
};
</script>

<style lang="scss" scoped>
</style>